package com.example.springboot_test.easyexcel.model;

import com.example.springboot_test.easyexcel.annotation.ReflectField;
import com.example.springboot_test.easyexcel.enums.BorderSideEnum;
import com.example.springboot_test.easyexcel.model.builder.StyleModelBuilder;
import com.example.springboot_test.easyexcel.model.common.BorderModel;
import com.example.springboot_test.easyexcel.model.common.CellShadingModel;
import com.example.springboot_test.easyexcel.model.common.FontModel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;

import java.util.Map;

/**
 * 样式信息类
 *
 * @author xudongmaster
 */
@EqualsAndHashCode
@Getter
public class StyleModel {
    /**
     * 样式是否追加
     */
    private final boolean isAppend;
    /**
     * 字体信息
     */
    private final FontModel fontModel;
    /**
     * 底纹信息
     */
    private CellShadingModel cellShadingModel;

    /**
     * 边框信息map
     */
    private final Map<BorderSideEnum, BorderModel> borderModelMap;
    /**
     * 水平对齐方式
     */
    @ReflectField(invokeMethodName = "setAlignment")
    private final HorizontalAlignment horizontalAlignment;
    /**
     * 垂直对齐方式
     */
    @ReflectField(invokeMethodName = "setVerticalAlignment")
    private final VerticalAlignment verticalAlignment;
    /**
     * 自动换行方式
     */
    @ReflectField(invokeMethodName = "setWrapText")
    private final Boolean wrapText;
    /**
     * 旋转角度(正数代表逆时针，负数代表顺时针)
     */
    @ReflectField(invokeMethodName = "setRotation")
    private final Short rotation;
    /**
     * 数据格式
     */
    @ReflectField(invokeMethodName = "setDataFormat")
    private final String dataFormat;

    /**
     * 自动收缩
     */
    @ReflectField(invokeMethodName = "setShrinkToFit")
    private final Boolean shrinkToFit;

    public StyleModel(StyleModelBuilder builder) {
        this.isAppend = builder.isAppend();
        this.fontModel = builder.getFontModel();
        this.cellShadingModel = builder.getCellShadingModel();
        this.borderModelMap = builder.getBorderModelMap();
        this.horizontalAlignment = builder.getHorizontalAlignment();
        this.verticalAlignment = builder.getVerticalAlignment();
        this.wrapText = builder.getWrapText();
        this.rotation = builder.getRotation();
        this.dataFormat = builder.getDataFormat();
        this.shrinkToFit = builder.getShrinkToFit();
    }

    /**
     * 生成字体样式信息
     *
     * @param fontModel 字体信息
     * @return 样式信息
     */
    public static StyleModel createFontStyleModel(FontModel fontModel) {
        return createFontStyleModel(fontModel, true);
    }

    /**
     * 生成字体样式信息
     *
     * @param fontModel 字体信息
     * @param isAppend  样式是否追加
     * @return 样式信息
     */
    public static StyleModel createFontStyleModel(FontModel fontModel, boolean isAppend) {
        return createStyleModel(fontModel, null, null, null, null
                , null, null, null, null, null
                , null, null, isAppend);
    }

    /**
     * 生成底纹信息
     *
     * @param cellShadingModel 底纹信息
     * @return 样式信息
     */
    public static StyleModel createCellShadingStyleModel(CellShadingModel cellShadingModel) {
        return createCellShadingStyleModel(cellShadingModel, true);
    }

    /**
     * 生成底纹信息
     *
     * @param cellShadingModel 底纹信息
     * @param isAppend         样式是否追加
     * @return 样式信息
     */
    public static StyleModel createCellShadingStyleModel(CellShadingModel cellShadingModel, boolean isAppend) {
        return createStyleModel(null, cellShadingModel, null, null, null
                , null, null, null, null, null
                , null, null, isAppend);
    }

    /**
     * 生成边框样式信息
     *
     * @param borderModel 边框信息
     * @return 样式信息
     */
    public static StyleModel createBorderStyleModel(BorderModel borderModel) {
        return createBorderStyleModel(borderModel, true);
    }

    /**
     * 生成边框样式信息
     *
     * @param borderModel 边框信息
     * @param isAppend    样式是否追加
     * @return 样式信息
     */
    public static StyleModel createBorderStyleModel(BorderModel borderModel, boolean isAppend) {
        return createBorderStyleModel(borderModel, borderModel, borderModel, borderModel, isAppend);
    }


    /**
     * 生成边框样式信息
     *
     * @param topBorderModel    上边框信息
     * @param rightBorderModel  右边框信息
     * @param bottomBorderModel 下边框信息
     * @param leftBorderModel   左边框信息
     * @return 样式信息
     */
    public static StyleModel createBorderStyleModel(BorderModel topBorderModel, BorderModel rightBorderModel, BorderModel bottomBorderModel
            , BorderModel leftBorderModel) {
        return createBorderStyleModel(topBorderModel, rightBorderModel, bottomBorderModel, leftBorderModel, true);
    }

    /**
     * 生成边框样式信息
     *
     * @param topBorderModel    上边框信息
     * @param rightBorderModel  右边框信息
     * @param bottomBorderModel 下边框信息
     * @param leftBorderModel   左边框信息
     * @param isAppend          样式是否追加
     * @return 样式信息
     */
    public static StyleModel createBorderStyleModel(BorderModel topBorderModel, BorderModel rightBorderModel, BorderModel bottomBorderModel
            , BorderModel leftBorderModel, boolean isAppend) {
        return createStyleModel(null, null, topBorderModel, rightBorderModel, bottomBorderModel
                , leftBorderModel, null, null, null, null, null
                , null, isAppend);
    }

    /**
     * 生成水平对齐方式信息
     *
     * @param horizontalAlignment 水平对齐方式
     * @return 样式信息
     */
    public static StyleModel createHorizontalAlignmentStyleModel(HorizontalAlignment horizontalAlignment) {
        return createHorizontalAlignmentStyleModel(horizontalAlignment, true);
    }

    /**
     * 生成水平对齐方式信息
     *
     * @param horizontalAlignment 水平对齐方式
     * @param isAppend            样式是否追加
     * @return 样式信息
     */
    public static StyleModel createHorizontalAlignmentStyleModel(HorizontalAlignment horizontalAlignment, boolean isAppend) {
        return createAlignmentStyleModel(horizontalAlignment, null, isAppend);
    }

    /**
     * 生成垂直对齐方式信息
     *
     * @param verticalAlignment 垂直对齐方式
     * @return 样式信息
     */
    public static StyleModel createVerticalAlignmentStyleModel(VerticalAlignment verticalAlignment) {
        return createVerticalAlignmentStyleModel(verticalAlignment, true);
    }

    /**
     * 生成垂直对齐方式信息
     *
     * @param verticalAlignment 垂直对齐方式
     * @param isAppend          样式是否追加
     * @return 样式信息
     */
    public static StyleModel createVerticalAlignmentStyleModel(VerticalAlignment verticalAlignment, boolean isAppend) {
        return createAlignmentStyleModel(null, verticalAlignment, isAppend);
    }

    /**
     * 生成对齐方式信息
     *
     * @param horizontalAlignment 水平对齐方式
     * @param verticalAlignment   垂直对齐方式
     * @return 样式信息
     */
    public static StyleModel createAlignmentStyleModel(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) {
        return createAlignmentStyleModel(horizontalAlignment, verticalAlignment, true);
    }

    /**
     * 生成对齐方式信息
     *
     * @param horizontalAlignment 水平对齐方式
     * @param verticalAlignment   垂直对齐方式
     * @param isAppend            样式是否追加
     * @return 样式信息
     */
    public static StyleModel createAlignmentStyleModel(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment
            , boolean isAppend) {
        return createStyleModel(null, null, null, null, null, null, horizontalAlignment
                , verticalAlignment, null, null, null, null, isAppend);
    }

    /**
     * 生成自动换行样式信息
     *
     * @param wrapText 自动换行
     * @return 样式信息
     */
    public static StyleModel createWrapTextStyleModel(Boolean wrapText) {
        return createWrapTextStyleModel(wrapText,true);
    }

    /**
     * 生成自动换行样式信息
     *
     * @param wrapText 自动换行
     * @param isAppend 样式是否追加
     * @return 样式信息
     */
    public static StyleModel createWrapTextStyleModel(Boolean wrapText, boolean isAppend) {

        return createStyleModel(null, null, null, null, null, null, null, null
                , wrapText, null, null, null, isAppend);
    }

    /**
     * 生成旋转角度样式信息
     *
     * @param rotation 旋转角度
     * @return 样式信息
     */
    public static StyleModel createRotationStyleModel(Short rotation) {
        return createRotationStyleModel(rotation, true);
    }

    /**
     * 生成旋转角度样式信息
     *
     * @param rotation 旋转角度
     * @param isAppend 样式是否追加
     * @return 样式信息
     */
    public static StyleModel createRotationStyleModel(Short rotation, boolean isAppend) {
        return createStyleModel(null, null, null, null, null, null, null, null
                , null, rotation, null, null, isAppend);
    }

    /**
     * 生成竖向文本样式信息
     *
     * @return 样式信息
     */
    public static StyleModel createVerticalTextStyleModel() {
        return createRotationStyleModel((short) 255, true);
    }

    /**
     * 生成竖向文本样式信息
     *
     * @param isAppend 样式是否追加
     * @return 样式信息
     */
    public static StyleModel createVerticalTextStyleModel(boolean isAppend) {
        return createRotationStyleModel((short) 255, isAppend);
    }


    /**
     * 生成数据格式样式信息
     *
     * @param dataFormat 数据格式
     * @return 样式信息
     */
    public static StyleModel createDataFormatStyleModel(String dataFormat) {
        return createDataFormatStyleModel(dataFormat, true);
    }

    /**
     * 生成数据格式样式信息
     *
     * @param dataFormat 数据格式
     * @param isAppend   样式是否追加
     * @return 样式信息
     */
    public static StyleModel createDataFormatStyleModel(String dataFormat, boolean isAppend) {
        return createStyleModel(null, null, null, null, null, null, null, null
                , null, null, dataFormat, null, isAppend);
    }

    /**
     * 生成自动收缩样式信息
     *
     * @param shrinkToFit 自动收缩
     * @return 样式信息
     */
    public static StyleModel createShrinkToFitStyleModel(Boolean shrinkToFit) {
        return createShrinkToFitStyleModel(shrinkToFit, true);
    }

    /**
     * 生成自动收缩样式信息
     *
     * @param shrinkToFit 自动收缩
     * @param isAppend    样式是否追加
     * @return 样式信息
     */
    public static StyleModel createShrinkToFitStyleModel(Boolean shrinkToFit, boolean isAppend) {
        return createStyleModel(null, null, null, null, null, null, null, null
                , null, null, null, shrinkToFit, isAppend);
    }

    /**
     * 生成样式信息
     *
     * @param fontModel           字体信息
     * @param cellShadingModel    底纹信息
     * @param topBorderModel      上边框信息
     * @param rightBorderModel    右边框信息
     * @param bottomBorderModel   下边框信息
     * @param leftBorderModel     左边框信息
     * @param horizontalAlignment 水平对齐方式
     * @param verticalAlignment   垂直对齐方式
     * @param wrapText            自动换行
     * @param rotation            旋转角度
     * @param dataFormat          数据格式
     * @param shrinkToFit         自动收缩
     * @param isAppend            样式是否追加
     * @return 样式信息
     */
    public static StyleModel createStyleModel(FontModel fontModel, CellShadingModel cellShadingModel, BorderModel topBorderModel
            , BorderModel rightBorderModel, BorderModel bottomBorderModel, BorderModel leftBorderModel, HorizontalAlignment horizontalAlignment
            , VerticalAlignment verticalAlignment, Boolean wrapText, Short rotation, String dataFormat, Boolean shrinkToFit, boolean isAppend) {
        return StyleModelBuilder.builder(isAppend)
                //设置字体样式
                .fontModel(fontModel)
                //底纹信息
                .cellShadingModel(cellShadingModel)
                //边框样式
                //上边框信息
                .borderModel(BorderSideEnum.TOP, topBorderModel)
                //右边框信息
                .borderModel(BorderSideEnum.RIGHT, rightBorderModel)
                //下边框信息
                .borderModel(BorderSideEnum.BOTTOM, bottomBorderModel)
                //左边框信息
                .borderModel(BorderSideEnum.LEFT, leftBorderModel)
                //对齐方式
                //水平对齐方式
                .horizontalAlignment(horizontalAlignment)
                //垂直对齐方式
                .verticalAlignment(verticalAlignment)
                //自动换行
                .wrapText(wrapText)
                //旋转角度
                .rotation(rotation)
                //数据格式
                .dataFormat(dataFormat)
                //自动收缩
                .shrinkToFit(shrinkToFit)
                .build();
    }

}